﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DAL;
using Entidades;
using System.Data;
using System.Data.Common;

namespace DAO
{
    public class AsistenciaDAO : DAOBase
    {
        private const string InsertProcedure = "PR_ASISTENCIA_I";
        private const string UpdateProcedure = "PR_ASISTENCIA_U";
        private const string SelectProcedure = "PR_ASISTENCIA_S";
        private const string SelectAllProcedure = "PR_ASISTENCIA_SA";
        private const string DeleteProcedure = "PR_ASISTENCIA_D";
        private const string SelectSalidaProcedure = "PR_ASISTENCIA_SALIDA";
        private const string SelectSalidasNullProcedure = "PR_ASISTENCIA_SALIDASNULL";
        private const string SelectAsistenciasProcedure = "PR_ASISTENCIA_SEARCH";

		public AsistenciaDAO() : base() {}

        #region VirtualProcedures

        public override string obtainInsertProcedure()
        {
            return InsertProcedure;
        }

        public override string obtainDeleteProcedure()
        {
            return DeleteProcedure;
        }

        public override string obtainUpdateProcedure()
        {
            return UpdateProcedure;
        }

        public override string obtainSelectProcedure()
        {
            return SelectProcedure;
        }

        public override string obtainSelectAllProcedure()
        {
            return SelectAllProcedure;
        }

        public string obtainSelectSalidaProcedure()
        {
            return SelectSalidaProcedure;
        }

        public string obtainSelectSalidasNullProcedure()
        {
            return SelectSalidasNullProcedure;
        }

        public string obtainSelectAsistenciasProcedure()
        {
            return SelectAsistenciasProcedure;
        }

        #endregion

        #region IDAO Members

        public override void cargarEntidad(EntidadBase entidad, IDataReader reader)
        {
            EntidadAsistencia asistencia = (EntidadAsistencia)entidad;
            object tempValue;
            // Campo Id
            asistencia.Id = Convert.ToInt32(reader["id_asistencia"]);
            // Resto de campos

            tempValue = reader["fechaYHoraEntrada"];
            if (tempValue.Equals(DBNull.Value))
            {
                asistencia.FechaYHoraEntrada = null;
            }
            else
            {
                asistencia.FechaYHoraEntrada = Convert.ToDateTime(tempValue);
            }

            tempValue = reader["fechaYHoraSalida"];
            if (tempValue.Equals(DBNull.Value))
            {
                asistencia.FechaYHoraSalida = null;
            }
            else
            {
                asistencia.FechaYHoraSalida = Convert.ToDateTime(tempValue);
            }
            
            tempValue = reader["fk_id_investigador"];
            if (tempValue.Equals(DBNull.Value))
            {
                asistencia.Investigador.Id = 0;
            }
            else
            {
                asistencia.Investigador.Id = Convert.ToInt32(tempValue);
            }
            
            //TODO: como manejamos la carga de ralaciones???
        }

        public override List<EntidadBase> cargar(IDataReader reader)
        {
            // Creo la lista vacia
            List<EntidadBase> listaEntidades = new List<EntidadBase>();
            // Itero en el data reader y cargo los datos basicos
            while (reader.Read())
            {
                EntidadAsistencia entity = new EntidadAsistencia();
                cargarEntidad(entity, reader);
                listaEntidades.Add(entity);
            }

            reader.Close();

            return listaEntidades;
        }

        /*
        * Devuelve un objeto EntidadAsistencia con el ultimo ingreso que hizo un investigador.
        * Se utiliza para realizar un update a la asistencia seteandole la fecha y hora de salida.
        */ 
        public EntidadAsistencia ultimoIngreso(int fkInvestigador)
        {
            bool opened = false;

            try
            {
                if (this.dalObject.IsConnectionClosed)
                {
                    opened = true;
                    this.dalObject.Open();
                }

                // Creo el comando
                IDbCommand cmd = null;
                cmd = this.dalObject.BuildCommand(this.obtainSelectSalidaProcedure(), new object[] { fkInvestigador });

                // Ejectuto el comando de lectura
                IDataReader reader = cmd.ExecuteReader();

                if (reader.Read())
                {
                    //Recupera y carga los datos de la entidad
                    EntidadAsistencia asistencia = new EntidadAsistencia();
                    this.cargarEntidad(asistencia, reader);
                    return asistencia;
                }
                else
                {
                    //No se recupero ninguna entidad de la base
                    return null;
                }
            }
            catch (DbException dbError)
            {
                throw new DALException("Error de base de datos al intentar eliminar entidad.", dbError);
            }
            catch (Exception error2)
            {
                throw new Exception("Error inesperado al intentar eliminar entidad.", error2);
            }
            finally
            {
                if (opened)
                {
                    this.dalObject.Close();
                }
            }
        }

        public List<EntidadAsistencia> leerSalidasNull()
        {
            bool opened = false;

            try
            {
                if (this.dalObject.IsConnectionClosed)
                {
                    opened = true;
                    this.dalObject.Open();
                }

                // Creo el comando
                IDbCommand cmd = null;
                cmd = this.dalObject.BuildCommand( this.obtainSelectSalidasNullProcedure() , null );

                // Ejectuto el comando de lectura
                IDataReader reader = cmd.ExecuteReader();

                List<EntidadAsistencia> listAsistencias = new List<EntidadAsistencia>();
                while( reader.Read() )
                {
                    //Recupera y carga los datos de la entidad
                    EntidadAsistencia asistencia = new EntidadAsistencia();
                    this.cargarEntidad(asistencia, reader);
                    listAsistencias.Add(asistencia);
                }
                return listAsistencias;
            }
            catch (DbException dbError)
            {
                throw new DALException("Error de base de datos al intentar eliminar entidad.", dbError);
            }
            catch (Exception error)
            {
                throw new DALException("Error inesperado al intentar eliminar entidad.", error);
            }
            finally
            {
                if (opened)
                {
                    this.dalObject.Close();
                }
            }
        }

        public List<EntidadAsistencia> listarAsistenciasInvestigador(int fkidInvestigador)
        {
            bool opened = false;

            try
            {
                if (this.dalObject.IsConnectionClosed)
                {
                    opened = true;
                    this.dalObject.Open();
                }

                // Creo el comando
                IDbCommand cmd = null;
                cmd = this.dalObject.BuildCommand(this.obtainSelectAsistenciasProcedure(), new object[] { fkidInvestigador });

                // Ejectuto el comando de lectura
                IDataReader reader = cmd.ExecuteReader();

                List<EntidadAsistencia> listAsistencias = new List<EntidadAsistencia>();
                while (reader.Read())
                {
                    //Recupera y carga los datos de la entidad
                    EntidadAsistencia asistencia = new EntidadAsistencia();
                    this.cargarEntidad(asistencia, reader);
                    listAsistencias.Add(asistencia);
                }
                return listAsistencias;
            }
            catch (DbException dbError)
            {
                throw new DALException("Error de base de datos al intentar cargar entidad.", dbError);
            }
            catch (Exception error)
            {
                throw new DALException("Error inesperado al intentar cargar entidad.", error);
            }
            finally
            {
                if (opened)
                {
                    this.dalObject.Close();
                }
            }
        }
        
        #endregion
    }
}
